package com.winit.commons.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *
 */
public class TaskContainer extends BaseTaskContainer{

    private TaskContainer() {
    }

    private static Integer thread_pool_count = 10;

    private static final TaskContainer TASK_CONTAINER = new TaskContainer();

    public static TaskContainer getInstance() {
        return TASK_CONTAINER;
    }

    public static ExecutorService TimeLimitedTaskPool = Executors.newFixedThreadPool(thread_pool_count);

    static Map<String, Task> taskMap = new HashMap<>();

    private static final Logger logger = LoggerFactory.getLogger(TaskContainer.class);

    static {
        try {
            Properties properties = PropertiesLoaderUtils.loadAllProperties("application.properties");
            thread_pool_count = Integer.parseInt(properties.getProperty("thread_pool_count"));
        } catch (Exception e) {
            logger.error("初始化TaskContainer异常。", e);
        }

    }

    /**
     * 添加任务
     *
     * @param task
     */
    public void addTask(Task task) {
        String taskId = task.getTaskId();
        logger.info("TaskContainer:添加任务.taskId=" + taskId);
        if (this.taskMap.containsKey(taskId)) {
            logger.error("TaskContainer:添加任务,相同任务已存在.taskId=" + taskId);
            return;
        }
        this.taskMap.put(taskId, task);
        task.setTaskStatus(Task.TaskStatus.STATUS_PREPARE);
        task.saveContainer(TaskContainer.getInstance());
        this.TimeLimitedTaskPool.submit(task);
    }

    /**
     * 根据taskid获取task对象
     *
     * @param taskId
     * @return
     */
    public Task getTask(String taskId) {
        logger.info("TaskContainer:获取任务.taskId=" + taskId);
        if (!this.taskMap.containsKey(taskId)) {
            logger.error("TaskContainer:获取任务,任务不存在.taskId=" + taskId);
            return null;
        }
        return this.taskMap.get(taskId);
    }

    /**
     * 检查taskMap中超时的任务并关闭
     */
    public synchronized void cleanTimeOutTask() {
        logger.info("TaskContainer:停止超时任务开始.");
        Iterator<String> iterator = this.taskMap.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            Task task = this.taskMap.get(key);
            Integer time = task.getLeftTime();
            logger.info("TaskContainer:停止超时任务.key=" + key + ",time=" + time);
            if (time <= 0) {
                task.stopTask();
                iterator.remove();
            }
        }
    }

    /**
     * task运行完毕后,删除taskMap内值
     */
    public synchronized void removeTask(String taskId) {
        logger.info("TaskContainer:线程关闭,删除taskMap内对象.taskId=" + taskId);
        if (!this.taskMap.containsKey(taskId)) {
            logger.info("TaskContainer:线程关闭,删除taskMap内对象,对象不存在.taskId=" + taskId);
            return;
        }

        this.taskMap.remove(taskId);
    }
}
